package com.company.project.robot.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.company.project.common.exception.BusinessException;
import com.company.project.common.utils.ExcelUtils;
import com.company.project.robot.entity.IdiomEntity;
import com.company.project.robot.entity.JokesEntity;
import com.company.project.robot.mapper.IdiomMapper;
import com.company.project.robot.service.IdiomService;
import com.company.project.robot.vo.ReptilesVo;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


@Slf4j
@Service("idiomService")
public class IdiomServiceImpl extends ServiceImpl<IdiomMapper, IdiomEntity> implements IdiomService {



    /**
     * @param china (字符串 汉字)
     * @return 汉字转拼音 其它字符不变
     */
    @Override
    public  String getPinyin(String china){
        HanyuPinyinOutputFormat formart = new HanyuPinyinOutputFormat();
        formart.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        formart.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        formart.setVCharType(HanyuPinyinVCharType.WITH_V);
        char[] arrays = china.trim().toCharArray();
        String result = "";
        try {
            for (int i=0;i<arrays.length;i++) {
                char ti = arrays[i];
                if(Character.toString(ti).matches("[\\u4e00-\\u9fa5]")){ //匹配是否是中文
                    String[] temp = PinyinHelper.toHanyuPinyinStringArray(ti,formart);
                    result += temp[0];
                }else{
                    result += ti;
                }
            }
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            e.printStackTrace();
        }

        return result;
    }


    /**
     * 导入模板
     * @param request
     * @param response
     * @throws IOException
     */
    @Override
    public void exportExcel(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String[] excelHeader = {"成语", "含义"};
        String[] columnNames = {"word", "remake"};
        int[] ds_format = {2, 2};
        String[] sumColumns = {"", ""};
        ExcelUtils.export("成语导入模板.xlsx", null, excelHeader, columnNames, sumColumns, ds_format, null,
                null, request, response);
    }


    /**
     * 导入
     *
     * @param file
     * @return
     * @throws Exception
     */
    @Override
    public String excelImport(MultipartFile file) throws Exception {
        //获取Excel格式
        int type = readExcel(file.getOriginalFilename());
        Workbook wb = null;
        //获取第一个工作表的数据（其他工作表数据不操作）
        Sheet sheet = null;
        //xls格式
        if (type == 1) {
            wb = new HSSFWorkbook(file.getInputStream());
        } else if (type == 2) {//xlsx格式
            wb = new XSSFWorkbook(file.getInputStream());
        } else {
            throw new BusinessException("请导入正确文件类型");
        }
        if (wb != null && wb.getNumberOfSheets() > 0) {
            for (int i = 0; i < wb.getNumberOfSheets(); i++) {
                if (wb.getSheetAt(i).getPhysicalNumberOfRows() > 0) {
                    sheet = wb.getSheetAt(i);
                    break;
                }
            }
        } else {
            throw new BusinessException("导入失败");
        }
        //判断第一行的第1、2列的名称，不符合则提示模板文件不对
        Row r = sheet.getRow(0);
        if (!r.getCell(0).getStringCellValue().equals("成语")
                || !r.getCell(1).getStringCellValue().equals("含义") ) {
            throw new BusinessException("请选择正确的模板文件再导入");
        }
        List<IdiomEntity> list = new ArrayList<>();
        for (int i = 1, length = sheet.getLastRowNum(); i <= length; i++) {
            Row row = sheet.getRow(i);
            //检查必填项是否有填写
            if (row.getCell(0) == null) {
                throw new BusinessException("部分数据导入成功<br>,已导入到第" + i + "行,在【" + (i + 1) + "】行有空数据");
            }
            String word = row.getCell(0).getStringCellValue();
            IdiomEntity entity = new IdiomEntity();
            entity.setWord(word);
            String wordS = String.valueOf(word.charAt(0));
            String wordE = String.valueOf(word.charAt(word.length()-1));
            entity.setWordE(wordE);
            entity.setWordS(wordS);
            entity.setPinyinE(getPinyin(wordE));
            entity.setPinyinS(getPinyin(wordS));
            if(null != row.getCell(1)){
                entity.setRemark(row.getCell(1).getStringCellValue());
            }
            entity.setDeleted(1);
            list.add(entity);
        }
        this.saveBatch(list);
        return "导入成功";
    }

    /**
     * 读取excel格式
     *
     * @param fileName
     * @return
     * @throws Exception
     */
    private int readExcel(String fileName) {
        String extString = fileName.substring(fileName.lastIndexOf("."));
        try {
            if (".xls".equals(extString)) {
                return 1;
            } else if (".xlsx".equals(extString)) {
                return 2;
            } else {
                return 0;
            }
        } catch (Exception e) {
            log.error("读取Excel文件异常" + e);
            throw new BusinessException("读取Excel文件异常");
        }
    }

    /**
     * 爬取成语大全数据接口
     * @param reptilesVo
     * @throws IOException
     */
    @Async
    @Override
    public void listSave(ReptilesVo reptilesVo) throws IOException {
        List<IdiomEntity> list = new ArrayList<>();
        for (int i = reptilesVo.getStart(); i <= reptilesVo.getEnd(); i++) {
            IdiomEntity idiomEntity = new IdiomEntity();
            //若有正文则新建对象，输入正文
            Connection connection_context = Jsoup
                    .connect("http://www.zd9999.com/cy/htm0/"+i+".htm")
                    .userAgent("Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)")
                    .timeout(3000);
            try {
                if(connection_context.execute().statusCode() == 200){
                    Document document_context = connection_context.get();
                    String value = document_context.select("b").get(0).text();
                    String explain = document_context.select(".td1o1").select("td").get(4).text();
                    String wordS = String.valueOf(value.charAt(0));
                    String wordE = String.valueOf(value.charAt(value.length()-1));
                    String pinyinS = getPinyin(wordS);
                    String pinyinE = getPinyin(wordE);
                    idiomEntity.setPinyinE(pinyinE);
                    idiomEntity.setPinyinS(pinyinS);
                    idiomEntity.setWordS(wordS);
                    idiomEntity.setWordE(wordE);
                    idiomEntity.setWord(value);
                    idiomEntity.setRemark(explain);
                    idiomEntity.setDeleted(1);
                    log.info("地址" + i + ": OK ");
                    log.info(JSON.toJSONString(idiomEntity));
                }else {
                    log.error("地址" + i + ": 不可用");
                }
            }catch (Exception ex){
                System.out.println("地址" + i + ": 不可用");
            }
            if(StrUtil.isNotEmpty(idiomEntity.getWord())){
                list.add(idiomEntity);
            }
        }
        this.remove(null);
        this.saveBatch(list);

    }



}